/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package proyecto1;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Observable;

/**
 *
 * @author grupo
 */
public class Plan extends Observable {

    private String codigo;
    private Calendar fechaDeRegistro;
    private String nombreDeSucursal;
    private String codigoDeSucursal;
    private String direccionDeSucursal;
    private TipoDePlan tipoDePlan;
    private String descripcionDelPlan;
    private String originador;
    private String administrator;
    private String lider;
    private String auditor;
    private Calendar fechaDeAsignacion;
    //private int cantidadDeActividades;
    private Calendar fechaRealizacionAnalisis;
    private Calendar fechaDeAuditoria;
    private String resolucionDelAuditor;
    private ArrayList<Actividad> listaDeActividades;
    private boolean planEfectivo;

    private static int cantPlanes = 0;
    private static int diasParaAsignar = 3;
    private static int diasParaAnalizar = 15;

    private String mensajeAlUsuario;

    /**
     *
     */
    public Plan() {
        this("");
    }

    /**
     *
     * @param pOriginador
     */
    public Plan(String pOriginador) {
        this.setOriginador(pOriginador);
        this.setFechaDeRegistro(Calendar.getInstance()); //Dia de hoy
        this.setCodigo("Plan_" + ++cantPlanes);

        this.setAuditor("");
        this.setLider("");
        this.setAdministrator("");
        this.setNombreDeSucursal("");
        this.setCodigoDeSucursal("");
        this.setMensajeAlUsuario("");
        this.setDireccionDeSucursal("");
        this.setDescripcionDelPlan("");
        this.setPlanEfectivo(true);
        this.resolucionDelAuditor = "";

        this.listaDeActividades = new ArrayList<Actividad>();
    }

    /**
     * @return the cantPlanes
     */
    public static int getCantPlanes() {
        return cantPlanes;
    }

    /**
     * @param aCantPlanes the cantPlanes to set
     */
    private static void setCantPlanes(int aCantPlanes) {
        cantPlanes = aCantPlanes;
    }

    /**
     * @return the diasParaAsignar
     */
    private static int getDiasParaAsignar() {
        return diasParaAsignar;
    }

    /**
     * @return the diasParaAnalizar
     */
    private static int getDiasParaAnalizar() {
        return diasParaAnalizar;
    }

    /**
     * @return the codigo
     */
    public String getCodigo() {
        return codigo;
    }

    /**
     * @return the fechaDeRegistro
     */
    public Calendar getFechaDeRegistro() {
        return fechaDeRegistro;
    }

    /**
     * @return the nombreDeSucursal
     */
    public String getNombreDeSucursal() {
        return nombreDeSucursal;
    }

    /**
     * @return the codigoDeSucursal
     */
    public String getCodigoDeSucursal() {
        return codigoDeSucursal;
    }
    
    /**
     *
     * @return
     */
    public int getIndiceEficiencia()
    {
        int indice = 0;
        if(fechaDeRegistro != null && fechaDeAsignacion != null && fechaRealizacionAnalisis != null)
        {
            //Primera condicion, para 100%
            Calendar comp = (Calendar)this.fechaDeRegistro.clone();
            comp.add(Calendar.DATE, 3);
        
            if(fechaUnoMenorIgualFecha2(fechaDeAsignacion,comp)){
                comp = (Calendar)this.fechaDeAsignacion.clone();
                comp.add(Calendar.DATE, 15);
                if(fechaUnoMenorIgualFecha2(fechaRealizacionAnalisis,comp)){
                    indice = 100;
                }
            }else{
                //Segunda condicion 70%
                comp = (Calendar)this.fechaDeRegistro.clone();
                comp.add(Calendar.DATE, 3);
                Calendar comp2 = (Calendar)fechaDeRegistro.clone();
                comp2.add(Calendar.DATE, 10);
                if(fechaDeAsignacion.after(comp) && fechaDeAsignacion.before(comp2))
                {
                    comp = (Calendar)this.fechaDeAsignacion.clone();
                    comp2 = (Calendar)comp.clone();
                    comp.add(Calendar.DATE, 18);
                    comp2.add(Calendar.DATE, 23);
                    if(fechaRealizacionAnalisis.after(comp) || fechaRealizacionAnalisis.before(comp2)){
                        indice = 70;
                    }
                }
            }
        }     
        
        if(indice == 0)
            indice = 50;
        
        return indice;
    }

    /**
     * @return the direccionDeSucursal
     */
    public String getDireccionDeSucursal() {
        return direccionDeSucursal;
    }

    /**
     * @return the tipoDePlan
     */
    public TipoDePlan getTipoDePlan() {
        return tipoDePlan;
    }

    /**
     * @return the descripcionDelPlan
     */
    public String getDescripcionDelPlan() {
        return descripcionDelPlan;
    }

    /**
     * @return the originador
     */
    public String getOriginador() {
        return originador;
    }

    /**
     * @return the administrator
     */
    public String getAdministrator() {
        return administrator;
    }

    /**
     * @return the lider
     */
    public String getLider() {
        return lider;
    }

    /**
     * @return the auditor
     */
    public String getAuditor() {
        return auditor;
    }

    /**
     * @return the fechaDeAsignacion
     */
    public Calendar getFechaDeAsignacion() {
        return fechaDeAsignacion;
    }

    /**
     * @return the fechaRealizacionAnalisis
     */
    public Calendar getFechaRealizacionAnalisis() {
        return fechaRealizacionAnalisis;
    }

    /**
     * @return the fechaDeAuditoria
     */
    public Calendar getFechaDeAuditoria() {
        return fechaDeAuditoria;
    }

    /**
     * @return the resolucionDelAuditor
     */
    public String getResolucionDelAuditor() {
        return this.resolucionDelAuditor;
    }

    /**
     * @return the listaDeActividades
     */
    public ArrayList<Actividad> getListaDeActividades() {
        return listaDeActividades;
    }
    
    /**
     *
     * @return
     */
    public int getCantidadActividades()
    {
        return listaDeActividades.size();
    }
    
    /**
     *
     * @param indice
     * @return
     */
    public Actividad getActividad(int indice)
    {
        return listaDeActividades.get(indice);
    }
    
    /**
     *
     * @return
     */
    public boolean tieneActividades()
    {
        return (this.listaDeActividades.size()>0?true:false);
    }

    /**
     * @param codigo the codigo to set
     */
    private void setCodigo(String codigo) {
        this.codigo = codigo;
    }

    /**
     * @param fechaDeRegistro the fechaDeRegistro to set
     */
    public void setFechaDeRegistro(Calendar fechaDeRegistro) {
        this.fechaDeRegistro = fechaDeRegistro;
    }

    /**
     * @param nombreDeSucursal the nombreDeSucursal to set
     */
    public void setNombreDeSucursal(String nombreDeSucursal) {
        if(!this.isPlanCerrado()){
            this.nombreDeSucursal = nombreDeSucursal;
        }else{
            this.setMensajeAlUsuario("Éste plan no se puede cambiar porque ya fue cerrado");
        }
    }

    /**
     * @param codigoDeSucursal the codigoDeSucursal to set
     */
    public void setCodigoDeSucursal(String codigoDeSucursal) {
        this.codigoDeSucursal = codigoDeSucursal;
    }

    /**
     * @param direccionDeSucursal the direccionDeSucursal to set
     */
    public void setDireccionDeSucursal(String direccionDeSucursal) {
        this.direccionDeSucursal = direccionDeSucursal;
    }

    /**
     * @param tipoDePlan the tipoDePlan to set
     */
    public void setTipoDePlan(TipoDePlan tipoDePlan) {
        if(!this.isPlanCerrado()){
            this.tipoDePlan = tipoDePlan;
            super.notifyObservers();
            super.setChanged();
        }else{
            this.setMensajeAlUsuario("Éste plan no se puede cambiar porque ya fue cerrado");
        }
    }

    /**
     * @param descripcionDelPlan the descripcionDelPlan to set
     */
    public void setDescripcionDelPlan(String descripcionDelPlan) {
        this.descripcionDelPlan = descripcionDelPlan;
    }

    /**
     * @param originador the originador to set
     */
    public void setOriginador(String originador) {
        this.originador = originador;
    }

    /**
     * @param pAdministrator
     * @return 
     */
    public boolean setAdministrator(String pAdministrator) {
        if (!pAdministrator.isEmpty()) {
            if (pAdministrator.compareTo(getOriginador()) != 0) {
                this.administrator = pAdministrator;
                return true;
            } else {
                this.setMensajeAlUsuario("El Administrator no puede ser la misma persona que el Originador");
                return false;
            }
        } else {
            this.administrator = "";
            return true;
        }
    }

    /**
     * @param pLider
     * @return 
     */
    public boolean setLider(String pLider) {
        if (!pLider.isEmpty()) {
            if (pLider.compareTo(this.getOriginador()) != 0 && pLider.compareTo(this.getAdministrator()) != 0) {
                Calendar fechaLimite = (Calendar) fechaDeRegistro.clone();
                fechaLimite.add(Calendar.DATE, Plan.getDiasParaAsignar());

                if (fechaLimite.after(Calendar.getInstance())) {
                    this.lider = pLider;
                    this.setFechaDeAsignacion(Calendar.getInstance());
                    return true;
                } else {
                    this.setMensajeAlUsuario("La fecha de asignacion del lider ha expirado.");
                    return false;
                }
            } else {
                this.setMensajeAlUsuario("El Lider no puede ser la misma persona que el Originador o el Administrador");
                return false;
            }
        } else {
            this.lider = "";
            return true;
        }
    }

    /**
     * @param pAuditor
     * @return 
     */
    public boolean setAuditor(String pAuditor) {
        if (!pAuditor.isEmpty()) {
            if (pAuditor.compareTo(this.originador) != 0 && pAuditor.compareTo(this.administrator) != 0
                    && pAuditor.compareTo(lider) != 0) {
                this.auditor = pAuditor;
                return true;
            } else {
                this.setMensajeAlUsuario("El Lider no puede ser la misma persona que el Originador o el Administrador o el Lider");
                return false;
            }
        } else {
            this.auditor = "";
            return true;
        }
    }

    /**
     * @param fechaDeAsignacion the fechaDeAsignacion to set
     */
    private void setFechaDeAsignacion(Calendar fechaDeAsignacion) {
        this.fechaDeAsignacion = fechaDeAsignacion;
    }

    /**
     * @param fechaRealizacionAnalisis the fechaRealizacionAnalisis to set
     * @return 
     */
    public boolean setFechaRealizacionAnalisis(Calendar fechaRealizacionAnalisis) {
        if (this.listaDeActividades.size() > 0) {
            if(this.hayActividadesAbiertas()){
                this.setMensajeAlUsuario("No se puede cerrar el plan si hay actividades inconclusas.");
                return false;
            }else{
                Calendar fechaLimite = (Calendar) this.getFechaDeAsignacion().clone();
                fechaLimite.add(Calendar.DATE, Plan.getDiasParaAnalizar());

                if (fechaLimite.after(Calendar.getInstance())) {
                    this.fechaRealizacionAnalisis = fechaRealizacionAnalisis;
                    return true;
                } else {
                    this.setMensajeAlUsuario("La fecha para realizar el analisis ha expirado");
                    return false;
                }
            }
        } else {
            this.setMensajeAlUsuario("El plan no se puede cerrar si no cuenta con actividades.");
            return false;
        }
    }
    
    private boolean hayActividadesAbiertas()
    {
        boolean siHay = false;
        
        for(Actividad act:listaDeActividades)
        {
            if(act.isActiva())
                siHay = true;
        }
        return siHay;
    }

    /**
     * @param fechaDeAuditoria the fechaDeAuditoria to set
     */
    private void setFechaDeAuditoria(Calendar fechaDeAuditoria) {
        this.fechaDeAuditoria = fechaDeAuditoria;
    }

    /**
     * @param presolucionDelAuditor
     * @return 
     */
    public boolean setResolucionDelAuditor(String presolucionDelAuditor) {
        if(presolucionDelAuditor.isEmpty()){
            this.setMensajeAlUsuario("La resolucion no tiene ninguna descipcion, por favor asigne una.");
            return false;
        }else{
            for(Actividad act:listaDeActividades){
                if(!act.isActividadEfectiva()){
                    this.setMensajeAlUsuario("No se puede asignar una resolucion, la fecha real de conclusion es posterior a la propuesta en actividad: " + act.getDescripcion());
                    this.setPlanEfectivo(false);
                    return false;
                }
            }   
            this.resolucionDelAuditor = presolucionDelAuditor;
            return true;
        } 
    }
    
    /**
     *
     * @return
     */
    public boolean isPlanCerrado()
    {
        if(!this.isPlanEfectivo() || !this.resolucionDelAuditor.isEmpty())
        {
            return true;
        }else{
            return false;
        }
    }

    /**
     * @param listaDeActividades the listaDeActividades to set
     */
    public void setListaDeActividades(ArrayList<Actividad> listaDeActividades) {
        this.listaDeActividades = listaDeActividades;
    }

    /**
     * @return the mensajeAlUsuario
     */
    public String getMensajeAlUsuario() {
        return mensajeAlUsuario;
    }

    /**
     * @param mensajeAlUsuario the mensajeAlUsuario to set
     */
    private void setMensajeAlUsuario(String mensajeAlUsuario) {
        this.mensajeAlUsuario = mensajeAlUsuario;
        setChanged();
        notifyObservers(mensajeAlUsuario);
    }
   
    /**
     * @param pactividad 
     */
    public void addActividad(Actividad pactividad) {
        getListaDeActividades().add(pactividad);
    }

    /**
     * @param planEfectivo the planEfectivo to set
     */
    public void setPlanEfectivo(boolean planEfectivo) {
        this.planEfectivo = planEfectivo;
    }

    /**
     * @return the planEfectivo
     */
    public boolean isPlanEfectivo() {
        return planEfectivo;
    }

    private boolean fechaUnoMenorIgualFecha2(Calendar fecha1, Calendar fecha2)
    {
        if(fecha1 != null && fecha2 != null){
            int anio1 = fecha1.get(Calendar.YEAR);
            int mes1 = fecha1.get(Calendar.MONTH);
            int dia1 = fecha1.get(Calendar.DATE);

            int anio2 = fecha2.get(Calendar.YEAR);
            int mes2 = fecha2.get(Calendar.MONTH);
            int dia2 = fecha2.get(Calendar.DATE);

            if((anio1 <= anio2) && (mes1 <= mes2) && (dia1 <= dia2))
            {
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
}
